package q47_permuteUnique;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;


public class Solution_1 {


    public static void main(String[] args) {
        Solution_1 s = new Solution_1();
        System.out.println(s.permute(new int[]{1,2,1}));
    }

    public List<List<Integer>> permute(int[] nums) {
        List<Integer> path = new ArrayList<>();
        List<List<Integer>> res = new ArrayList<>();

        // 还有一个特殊的地方，需要先对nums进行排序
        Arrays.sort(nums);
        int[] used = new int[nums.length];
        arrange(res,path,nums,0,used,12);
        return res;
    }

    private static void arrange(List<List<Integer>> res,List<Integer> path, int[] candidates, int index, int[] used, int pre) {
        if (path.size() == candidates.length) {
            res.add(new ArrayList<>(path));
            return;
        }
        // prev必须定义在外部
        // 我们同时参考传入的参数pre以及prev，假设这两者都是为了识别排列过程中上一个数是否与此数相同
        // 1 如果使用pre 那么在进入第二次递归时，pre会传入1这个值，就会导致直接跳过了
        // 2 而正确的情况应该是，prev独立于函数外，每次循环开始前定义该数字，如果循环中已经加入过了这个数字，再进行跳过
        // 这样就不会导致反复跳过一个相同的数字
        int prev = 77;
        for(int i = 0;i < candidates.length;i++) {
            // 关键在于识别哪些数是用过的，所以需要一个used数组，每次把用过的数字标一
            if (used[i] == 1 || prev == candidates[i]){
                continue;
            }
            used[i] = 1;
            prev = candidates[i];
            path.add(candidates[i]);
            // 开始递归，通过画图很容易得到这一步的实际意义，就是将这个节点作为父节点，重新开始一个n叉树
            arrange(res,path,candidates,i,used,pre);

            used[i] = 0;
            path.remove(path.size()-1);


        }


    }
}
